/**
 * \file mainsdl.c
 * \brief 
 * \author Somayya ELMATA
 * \author Theo BRASSEUR
 * \version 0.1
 * \date 25/12/2013
 *
 * Ce fichier main pour l'affichage en SDL
 *
 */
 
#ifndef UICONSOLE
#define UICONSOLE
#include "interface-console.h"
#endif

#ifndef TSM
#define TSM 
#include "tsm.h"
#endif

#ifndef ALGOGEN
#define ALGOGEN
#include "algo-genetique.h"
#endif

#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>

void pause();
void affciher_villes(City* c,int nbrc,SDL_Surface *ecran);
void afficher_chemin(City* c,int nbcrc, SDL_Surface *ecran);
void drawLine(SDL_Surface* surf,int x1,int y1, int x2,int y2, int R, int G, int B);
void PutPixel(SDL_Surface *surface, int x, int y, unsigned long pixel);
unsigned long Color(int R, int G, int B);
void afficher_population(Population p,SDL_Surface *ecran);

int main(int argc, char **argv)
{

    SDL_Surface *ecran = NULL, *plan = NULL,*texte;
    SDL_Surface *boutton = NULL;
    SDL_Rect pos;
    Population p;
    Population *tmp = NULL;
   	City *city = NULL;
	FILE* file = NULL;
	int continuer = 1;
    SDL_Event event;
    TTF_Font *police = NULL;
    SDL_Color cNoire = {0, 0, 0};
    SDL_Color cRouge = {255, 0, 0};
    
    
	int crit=0,nbrcity = 0, quota = 0, taille = 0,generation=0,met_sel=0,x=0;
	float proba_mut = 0.0;
	float proba_cro = 0.0;
	double seuil=0.0f;
	
    
    // init ecran
    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();
    police = TTF_OpenFont("src/Calibri.ttf", 35);
    ecran=SDL_SetVideoMode(1000, 600, 32, SDL_HWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF );
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 200, 200, 200));
    SDL_WM_SetCaption("Algo Genetique pour TSP", NULL);
   
    plan = SDL_CreateRGBSurface(SDL_SWSURFACE, 800, 500, 32, 0, 0, 0, 0);
    pos.x=50;pos.y=50;
    SDL_FillRect(plan, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
    SDL_BlitSurface(plan, NULL, ecran, &pos);

    texte = TTF_RenderText_Blended(police, "Resolution de TSP avec un Algorithme Genetique", cNoire);
	pos.x=100;pos.y=5;
	SDL_BlitSurface (texte, NULL, ecran, &pos);

    
    boutton = SDL_CreateRGBSurface(SDL_SWSURFACE, 130, 50, 32, 0, 0, 0, 0);    
    SDL_FillRect(boutton, NULL, SDL_MapRGB(ecran->format, 100, 100, 100));
    
    police = TTF_OpenFont("src/Calibri.ttf", 15); 
    pos.x=860;pos.y=500;
    SDL_BlitSurface (boutton, NULL, ecran, &pos);
    texte = TTF_RenderText_Blended(police, "Algo Genetique", cNoire);
	pos.x=870;pos.y=510;
	SDL_BlitSurface (texte, NULL, ecran, &pos);

	pos.x=860;pos.y=440;
    SDL_BlitSurface (boutton, NULL, ecran, &pos);
	texte = TTF_RenderText_Blended(police, "Affichier Population", cNoire);
	pos.x=865;pos.y=450;
	SDL_BlitSurface (texte, NULL, ecran, &pos);
	
    pos.x=860;pos.y=380;
    SDL_BlitSurface (boutton, NULL, ecran, &pos);
	texte = TTF_RenderText_Blended(police, "Charger Fichier", cNoire);
	pos.x=870;pos.y=390;
	SDL_BlitSurface (texte, NULL, ecran, &pos);
	
	police = TTF_OpenFont("src/Calibri.ttf", 20);
	texte = TTF_RenderText_Blended(police, "Attention le remplissage des parametres est sur la console !", cRouge);
    pos.x=150;pos.y=570;
	SDL_BlitSurface (texte, NULL, ecran, &pos);
	
	SDL_Flip(ecran);
    
    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
			case SDL_MOUSEBUTTONUP :
				if (event.button.button == SDL_BUTTON_LEFT)
				{
					if(event.button.x > 860 && event.button.x < 990
					&& event.button.y > 380 && event.button.y < 430)
					{
						pos.x=50;pos.y=50;
						SDL_BlitSurface(plan, NULL, ecran, &pos);
						load_file(&city, &nbrcity);
						affciher_villes(city,nbrcity,ecran);
						SDL_Flip(ecran);
					}
					if(event.button.x > 860 && event.button.x < 990
					&& event.button.y > 440 && event.button.y < 490)
					{
						printf("\nEntrez la taille de la population :");
						scanf("%d",&taille);
						p = init_population(taille, city, nbrcity, city[0]);
						afficher_population(p,ecran);
						SDL_Flip(ecran);
					}
					if(event.button.x > 860 && event.button.x < 990
					&& event.button.y > 500 && event.button.y < 550)
					{
						recup_parametre(&crit,&seuil,&taille, &quota, &met_sel, &proba_cro, &proba_mut, &generation);
						p = init_population(taille, city, nbrcity, city[0]);
						x=generation;
						do
						{
							evaluation(p);
							tmp=selection(&p, quota-(x-generation), met_sel, nbrcity);
							p=*tmp;
							p = mutation(p, proba_mut);
							croisement(p, proba_cro);
							//if(crit==1) // pour ne pas deminuer la selection en mode seuil
							generation--;
							pos.x=50;pos.y=50;
							SDL_BlitSurface(plan, NULL, ecran, &pos);
							affciher_villes(city,nbrcity,ecran);
							afficher_population(p,ecran);
							SDL_Flip(ecran);
							
						}while( generation > 0 && seuil <= compute_path(plus_court_chemin(p)));
						printf("fin de l'algo genetique\n");
					}
				}
				break;
            case SDL_QUIT:
                continuer = 0;
                
        }
    }
    
	
    SDL_FreeSurface(plan);
    SDL_FreeSurface(ecran);
    SDL_FreeSurface(boutton);
    free(p);
    TTF_CloseFont(police);
    TTF_Quit();
    SDL_Quit();

    return EXIT_SUCCESS;
}


void affciher_villes(City* c,int nbrc,SDL_Surface *ecran)
{
    int i;
    SDL_Surface *rectangle2 = NULL;
    SDL_Rect poss;
    int r=255,g=0,b=200;
    for(i=0;i<nbrc;i++)
    {
        rectangle2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 6, 6, 32, 0, 0, 0, 0);

        poss.x=c[i].x+50;
        poss.y=c[i].y+50;
        SDL_FillRect(rectangle2, NULL, SDL_MapRGB(ecran->format, r, g,b));
        SDL_BlitSurface(rectangle2, NULL, ecran, &poss); // Collage de la surface sur l'écran
        if (r<0 || r>255)r=255;
        if (g<0 || g>255)g=0;
        if (b<0 || b>255)b=200;
        r-=70;
        g+=60;
        b-=20;

        SDL_FreeSurface(rectangle2);
    }
}

void afficher_chemin(City* c,int nbrc, SDL_Surface *ecran)
{
    int i;

    for(i=0;i<nbrc-1;i++)
    {
        drawLine(ecran,c[i].x+50,c[i].y+50,c[i+1].x+50,c[i+1].y+50,55,55,55);
    }
    drawLine(ecran,c[nbrc-1].x+50,c[nbrc-1].y+50,c[0].x+50,c[0].y+50,55,55,55);
}

void afficher_population(Population p,SDL_Surface *ecran)
{
    Population courant;
    courant=p;

    while(courant !=NULL)
    {
        afficher_chemin((courant->trajet).city,(courant->trajet).longueur,ecran);
        courant=courant->next;
    }
}



void drawLine(SDL_Surface* surf,int x1,int y1, int x2,int y2, int R, int G, int B)  // Bresenham
{
	unsigned long couleur = Color(R, G, B);
	int x,y;
	int Dx,Dy;
	int xincr,yincr;
	int erreur;
	int i;

	Dx = abs(x2-x1);
	Dy = abs(y2-y1);
	if(x1<x2)
		xincr = 1;
	else
		xincr = -1;
	if(y1<y2)
		yincr = 1;
	else
		yincr = -1;

	x = x1;
	y = y1;
	if(Dx>Dy)
	{
		erreur = Dx/2;
		for(i=0;i<Dx;i++)
		{
			x += xincr;
			erreur += Dy;
			if(erreur>Dx)
			{
				erreur -= Dx;
				y += yincr;
			}
			PutPixel(surf,x, y,couleur);
		}
	}
	else
	{
		erreur = Dy/2;
		for(i=0;i<Dy;i++)
		{
			y += yincr;
			erreur += Dx;

			if(erreur>Dy)
			{
				erreur -= Dy;
				x += xincr;
			}
			PutPixel(surf,x, y,couleur);
		}
	}
}

unsigned long Color(int R, int G, int B)
{//Convertit RGB en long
	return 65536*R + 256*G + B;
}

void PutPixel(SDL_Surface *surface, int x, int y, unsigned long pixel)
{
	int bpp = surface->format->BytesPerPixel;
	unsigned char *p = (unsigned char *)surface->pixels + y * surface->pitch + x * bpp;
	if (bpp==4)
		*(unsigned long*)p = pixel;
}
